package br.com.q7solucoes.commons.sendmail;

import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.Authenticator;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;

/**
 * Classe para enviar email.
 *
 * @author Elenilson Vieira - elenilson[at]elenilsonvieira.com
 * @since 8 de dezembro de 2010
 * @version 1.1
 * @see www.elenilsonvieira.com
 */
public class SendMail {

    private String mailSMTPServer;
    private String mailSMTPServerPort;

    public enum MessageType {TEXT, HTML}

    /*
     * quando instanciar um Objeto ja sera atribuido o servidor SMTP do GMAIL
     * e a porta usada por ele
     */
    public SendMail() { //Para o GMAIL
        mailSMTPServer = "smtp.gmail.com";
        mailSMTPServerPort = "465";
    }
    /*
     * caso queira mudar o servidor e a porta, so enviar para o contrutor
     * os valor como string
     */

    public SendMail(String mailSMTPServer, String mailSMTPServerPort) { //Para outro Servidor
        this.mailSMTPServer = mailSMTPServer;
        this.mailSMTPServerPort = mailSMTPServerPort;
    }

    /**
     * Envia um email
     *
     * @param from o email fonte
     * @param passwordFrom a senha do email fonte
     * @param to os destinatarios (email1@eu.com, email2@eu.com, ...)
     * @param subject o assunto
     * @param message o corpo do email
     * @param messageType o tipo da mensagem
     * @param fileName o arquivo a ser enviado
     */
    public void sendMail(String from, String passwordFrom, String to, String subject, 
            String message, MessageType messageType, String fileName) {

        Properties props = new Properties();

        // quem estiver utilizando um SERVIDOR PROXY descomente essa parte e atribua as propriedades do SERVIDOR PROXY utilizado
        /*
        props.setProperty("proxySet","true");
        props.setProperty("socksProxyHost","192.168.155.1"); // IP do Servidor Proxy
        props.setProperty("socksProxyPort","1080");  // Porta do servidor Proxy
         */

        props.put("mail.transport.protocol", "smtp"); //define protocolo de envio como SMTP
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", mailSMTPServer); //server SMTP do GMAIL
        props.put("mail.smtp.auth", "true"); //ativa autenticacao
        props.put("mail.smtp.user", from); //usuario ou seja, a conta que esta enviando o email (tem que ser do GMAIL)
        props.put("mail.debug", "true");
        props.put("mail.smtp.port", mailSMTPServerPort); //porta
        props.put("mail.smtp.socketFactory.port", mailSMTPServerPort); //mesma porta para o socket
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");

        //Cria um autenticador que sera usado a seguir
        SimpleAuth auth = new SimpleAuth(from, passwordFrom);

        //Session - objeto que ira realizar a conexão com o servidor
        /*Como há necessidade de autenticação é criada uma autenticacao que
         * é responsavel por solicitar e retornar o usuário e senha para
         * autenticação */
        Session session = Session.getDefaultInstance(props, auth);
        //session.setDebug(true); //Habilita o LOG das ações executadas durante o envio do email

        //Objeto que contém a mensagem
        MimeMessage msg = new MimeMessage(session);

        try {
            //Setando o destinatário
            msg.addRecipients(Message.RecipientType.BCC, to);

            //Setando a origem do email
            msg.setFrom(new InternetAddress(from));

            //Setando o assunto
            msg.setSubject(subject);

            //Seta o texto na primeira parte do email
            MimeBodyPart mimeBodyPartText = new MimeBodyPart();
            
            if(messageType == MessageType.TEXT)
                mimeBodyPartText.setText(message);
            else if(messageType == MessageType.HTML)
                mimeBodyPartText.setContent(message, "text/html");

            //Setando o anexo na segunda parte do email
            MimeBodyPart mimeBodyPartAttach = null;
            boolean containsAttachment = fileName != null && !fileName.isEmpty();
            if(containsAttachment){
                mimeBodyPartAttach = new MimeBodyPart();
                FileDataSource fileDataSource = new FileDataSource(fileName);
                mimeBodyPartAttach.setDataHandler(new DataHandler(fileDataSource));
                mimeBodyPartAttach.setFileName(fileName);
            }

            //Cria o email com duas partes
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(mimeBodyPartText);

            if(containsAttachment)
                multipart.addBodyPart(mimeBodyPartAttach);

            //Seta as duas partes como conteudo
            msg.setContent(multipart);
        } catch (Exception e) {
            System.out.println(">> Erro: Completar Mensagem");
            e.printStackTrace();
        }

        //Objeto encarregado de enviar os dados para o email
        Transport tr;
        try {
            tr = session.getTransport("smtp"); //define smtp para transporte
            /*
             *  1 - define o servidor smtp
             *  2 - seu nome de usuario do gmail
             *  3 - sua senha do gmail
             */
            tr.connect(mailSMTPServer, from, passwordFrom);
            msg.saveChanges(); // don't forget this
            //envio da mensagem
            tr.sendMessage(msg, msg.getAllRecipients());
            tr.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.out.println(">> Erro: Envio Mensagem");
            e.printStackTrace();
        }

    }
}
class SimpleAuth extends Authenticator {

    public String username = null;
    public String password = null;

    public SimpleAuth(String user, String pwd) {
        username = user;
        password = pwd;
    }

    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username, password);
    }
}
